home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 2
/
LIGHT-ROM 2 (Amiga Library Services)(1995).iso
/
programs
/
pc
/
l_parser
/
dxf2lw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-23
|
18KB
|
596 lines
/*
DXFTOLW.C
Copyright (C) 1994 Earl C. Terwilliger
158 Eades Drive
Irvine, KY 40336
Phone (606)-723-5718
Internet: aisterwi@acs.eku.edu
*/
#define LINESIZE 256
#define DXF_VERTICES 4
#define MAX_SAVE 10
#define MAX_POINTS 65532
#define CR 0x0A
#define LF 0x0D
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
FILE *fp1;
int fp2, fp3;
static unsigned char buf[LINESIZE],buf1[LINESIZE];
static unsigned int poly=0, color=0, layer=0;
static int vertices = -1;
static float prev_xyz[DXF_VERTICES*MAX_SAVE][3];
static unsigned long prev_index[DXF_VERTICES*MAX_SAVE];
float polygon[DXF_VERTICES][3];
static unsigned long polygons = 0l, totpoints = 0l;
static unsigned long triangles= 0l, twoptpols = 0l;
static unsigned long file_size = 0l;
static unsigned int surfaces[8][2];
static unsigned int totsurfaces = 0;
static unsigned int xyccpoly=0,yzccpoly=0,xzccpoly=0;
static unsigned int xycpoly=0,yzcpoly=0,xzcpoly=0;
static unsigned int xypols=0,yzpols=0,xzpols=0,nonpols=0;
static double area;
#pragma pack(1)
static struct {
char form_hdr[4];
long form_len;
char form_lwob[4];
} FORM = { { 'F','O','R','M'}, 0L, { 'L','W','O','B'} };
static struct {
char layr_hdr[4];
long layr_len;
int layr_id;
int layr_nbr;
char layr_name[8];
} LAYR = { { 'L','A','Y','R'},
12L, 0x0100, 0x0000,
{ 'n','o','n','a','m','e','\0','\0' } };
static struct {
char pnts_hdr[4];
long pnts_len;
float xyz[3];
} PNTS = { { 'P','N','T','S'}, 0l, 0l, 0l, 0l };
static struct {
unsigned int layer;
unsigned int vertices;
unsigned int color;
unsigned long index[DXF_VERTICES];
unsigned int unique;
float xyz[DXF_VERTICES][3];
} POLY;
static struct {
char pols_hdr[4];
long pols_len;
unsigned int pols_points[6];
} POLS = { { 'P','O','L','S'}, 0L, { 4,0,0,0,0,1 } };
static struct {
char srfs_hdr[4];
long srfs_len;
char srfs[8][6];
} SRFS = {
{ 'S', 'R', 'F', 'S' } , 48l,
{ { 'P', 'E', 'N', '0', '\0', '\0' },
{ 'P', 'E', 'N', '1', '\0', '\0' },
{ 'P', 'E', 'N', '2', '\0', '\0' },
{ 'P', 'E', 'N', '3', '\0', '\0' },
{ 'P', 'E', 'N', '4', '\0', '\0' },
{ 'P', 'E', 'N', '5', '\0', '\0' },
{ 'P', 'E', 'N', '6', '\0', '\0' },
{ 'P', 'E', 'N', '7', '\0', '\0' } }
};
static struct {
char surf_hdr[4];
char surf_len[4];
char surf_name[6];
char surf_color[4];
char surf_color_len[2];
char surf_color_rgb1[4];
char surf_flag[4];
char surf_flag_len[2];
char surf_flag_flags[2];
char surf_diff[4];
char surf_diff_len[2];
char surf_diff_diff[2];
} SURF[8] = {
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '0', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { '\0', '\0', '\0', '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '1', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { 0xFF, '\0', '\0', '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{ { 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '2', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { 0xFF, 0xFF, '\0', '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{ { 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '3', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { '\0', 0xFF, '\0', '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '4', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { '\0', 0xFF, 0xFF, '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '5', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { '\0', '\0', 0xFF, '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '6', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { 0xFF, '\0', 0xFF, '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } },
{{ 'S', 'U', 'R', 'F' }, { 0x00, 0x00, 0x00, 0x20 },
{ 'P', 'E', 'N', '7', '\0', '\0' },
{ 'C', 'O', 'L', 'R' }, { 0x00, 0x04 }, { 0xFF, 0xFF, 0xFF, '\0' },
{ 'F', 'L', 'A', 'G' }, { 0x00, 0x02 }, { 0x00, 0x04 },
{ 'D', 'I', 'F', 'F' }, { 0x00, 0x02 }, { 0x00, 0xFF } } };
main(argc,argv)
int argc;
char *argv[];
{
unsigned char rawfile[64], infile[64], outfile[64];
unsigned int c,d,e;
float t;
int code,debug=0;
if (argc < 2) syntax(argv[0]);
strcpy(infile,argv[1]);
if (!strchr(infile,'.')) strcat(infile,".DXF");
if (!(fp1 = fopen(infile,"rb"))) {
printf("Cannot open input file %s!\n",infile);
exit(1);
}
if ((argv[argc-1][0] == '-') && (toupper(argv[argc-1][1]) == 'D')) {
debug = 1;
--argc;
}
if (argc < 3) {
strcpy(outfile,infile);
strcpy(strchr(outfile,'.'),".OBJ");
}
else {
strcpy(outfile,argv[2]);
if (!strchr(infile,'.')) strcat(infile,".OBJ");
}
strcpy(rawfile,infile);
strcpy(strchr(rawfile,'.'),".RAW");
if (!(fp2 = open(outfile,O_BINARY|O_CREAT|O_WRONLY|O_TRUNC))) {
printf("Cannot open output file %s!\n",outfile);
fclose(fp1);
exit(1);
}
if (!(fp3 = open(rawfile,O_BINARY|O_CREAT|O_WRONLY|O_TRUNC))) {
printf("Cannot open temporary output file %s!\n",rawfile);
fclose(fp1);
close(fp2);
exit(1);
}
printf("\n%s Started\n",argv[0]);
printf("Reading DXF File - Creating RAW file ....");
totpoints = polygons = 0l;
while(getline(fp1,buf)) {
if(!getline(fp1,buf1)) {
printf("\nError - Group Code %s with no data\n",buf);
fclose(fp1);
close(fp2);
close(fp3);
unlink(outfile);
unlink(rawfile);
break;
}
code = atoi(buf);
switch (code) {
case 0:
if (poly) {
lwout(vertices);
vertices = -1;
color = layer = 0;
poly = 0x00;
}
if (strstr(buf1,"3DFACE")) { poly = 0x80; ++polygons; }
break;
case 8:
layer = atoi(buf1);
break;
case 10:
case 11:
case 12:
case 13:
++vertices;
polygon[vertices][0] = atof(buf1);
break;
case 20:
case 21:
case 22:
case 23:
polygon[vertices][1] = atof(buf1);
break;
case 30:
case 31:
case 32:
case 33:
polygon[vertices][2] = atof(buf1);
break;
case 62:
color = atoi(buf1);
break;
case 999:
break;
default :
break;
}
}
if (poly) lwout(vertices);
for(c=0;c<8;++c) {
if (surfaces[c][0] == 1) {
++totsurfaces;
surfaces[c][1] = totsurfaces;
}
}
printf("\nPoints %ld [unique]\nPolygons %ld ",totpoints,polygons);
printf("[%ld triangles] [%ld 2-point polygons]\n",triangles,twoptpols);
printf("Surfaces %u\n",totsurfaces);
fclose(fp1);
close(fp3);
if (totpoints > MAX_POINTS) {
printf("\nERROR - maximum points exceeded.\nThe limit is %u points.\n",MAX_POINTS);
close(fp2);
unlink(outfile);
unlink(rawfile);
exit(99);
}
file_size = 4l;
file_size += 8l;
file_size += totpoints * 12l;
file_size += 8l + (long)totsurfaces*6l;
file_size += 8l;
file_size += (polygons * 12l) - (triangles * 2l) - (twoptpols * 4l);
file_size += (long)totsurfaces*40l;
printf("Creating %s file size %ld\n",outfile,file_size+8l);
FORM.form_len = file_size;
rev_long((char *)&FORM.form_len);
write(fp2,(char *)&FORM,sizeof(FORM));
if (!(fp3 = open(rawfile,O_BINARY|O_RDONLY))) {
printf("Cannot open temporary output file %s!\n",rawfile);
close(fp2);
exit(1);
}
printf("\nRAW file PASS 1 - Creating PNTS chunk ....");
PNTS.pnts_len = (long)totpoints*12l;
rev_long((char *)&PNTS.pnts_len);
write(fp2,(char *)&PNTS,8);
totpoints = polygons = 0;
while(read(fp3,&POLY,sizeof(POLY))) {
polygons += 1;
for(c=0;c<DXF_VERTICES;++c) {
if (!(POLY.unique & (0x01<<c))) continue;
totpoints += 1;
t = POLY.xyz[c][1];
POLY.xyz[c][1] = POLY.xyz[c][2];
POLY.xyz[c][2] = t;
for(d=0;d<3;++d) rev_long(&POLY.xyz[c][d]);
write(fp2,(char *)&POLY.xyz[c],12);
}
}
close(fp3);
printf("\nPoints %ld [unique] Polygons %ld\n",totpoints,polygons);
printf("\nWriting to output - Creating SRFS chunk ....");
printf("\nSurfaces %u\n",totsurfaces);
SRFS.srfs_len = (long)totsurfaces*6l;
rev_long((char *)&SRFS.srfs_len);
write(fp2,(char *)&SRFS,8);
for(c=0;c<8;++c) if(surfaces[c][0] == 1) write(fp2,(char *)&SRFS.srfs[c],6);
if (!(fp3 = open(rawfile,O_BINARY|O_RDONLY))) {
printf("Cannot open temporary output file %s!\n",rawfile);
close(fp2);
exit(1);
}
printf("\nRAW file PASS 2 - Creating POLS chunk ....");
POLS.pols_len = (polygons * 12l) - (triangles * 2l) - (twoptpols * 4l);
rev_long((char *)&POLS.pols_len);
write(fp2,(char *)&POLS,8);
totpoints = polygons = 0;
while(read(fp3,&POLY,sizeof(POLY))) {
poly_area_xy();
polygons += 1;
totpoints += POLY.vertices;
POLS.pols_points[0] = POLY.vertices;
POLS.pols_points[POLY.vertices+1] = surfaces[POLY.color][1];
for(e=0;e<(POLY.vertices+2);++e) rev_int((char *)&POLS.pols_points[e]);
write(fp2,(char *)POLS.pols_points,(4+(POLY.vertices*2)));
}
close(fp3);
printf("\nVertices %ld Polygons %ld\n",totpoints,polygons);
printf("Front [xy] Polygons %2u [%2u clockwise] [%2u counterclockwise]\n",
xypols,xycpoly,xyccpoly);
printf("Side [yz] Polygons %2u [%2u clockwise] [%2u counterclockwise]\n",
yzpols,yzcpoly,yzccpoly);
printf("Top [xz] Polygons %2u [%2u clockwise] [%2u counterclockwise]\n",
xzpols,xzcpoly,xzccpoly);
printf("Non visible Polygons %2u [Includes 2-point polygons]\n",nonpols);
printf("\nInternal data used - Creating SURF chunk ....");
for (c=0;c<8;++c) if(surfaces[c][0] == 1) write(fp2,(char *)&SURF[c],40);
close(fp2);
if (!debug) unlink(rawfile);
printf("\nProgram complete.\n");
exit(0);
}
lwout(vertices)
unsigned int vertices;
{
int c,d;
if (vertices < 0) return(0);
++vertices;
if (vertices != DXF_VERTICES) {
printf("\nDXF file polygon vertices != %d\n",DXF_VERTICES);
exit(99);
}
while (color > 7) color -= 7;
surfaces[color][0] = 1;
POLY.vertices = vertices;
POLY.color = color;
POLY.layer = layer;
POLY.unique = 0x00;
for(c=0;c<vertices;++c) {
for(d=0;d<3;++d) POLY.xyz[c][d] = polygon[c][d];
d = check_unique(POLY.xyz[c][0],POLY.xyz[c][1],POLY.xyz[c][2]);
if (d < DXF_VERTICES*MAX_SAVE) POLY.index[c] = prev_index[d];
else {
POLY.index[c] = totpoints;
POLY.unique |= (0x01 << c);
totpoints += 1;
bubble_up(POLY.xyz[c][0],POLY.xyz[c][1],POLY.xyz[c][2],POLY.index[c]);
}
}
if ((POLY.xyz[2][0] == POLY.xyz[3][0]) &&
(POLY.xyz[2][1] == POLY.xyz[3][1]) &&
(POLY.xyz[2][2] == POLY.xyz[3][2])) {
POLY.vertices -= 1;
if ((POLY.xyz[2][0] == POLY.xyz[0][0]) &&
(POLY.xyz[2][1] == POLY.xyz[0][1]) &&
(POLY.xyz[2][2] == POLY.xyz[0][2])) {
POLY.vertices -= 1;
twoptpols += 1;
}
else triangles += 1;
}
write(fp3,(char *)&POLY,sizeof(POLY));
return(0);
}
check_unique(x,y,z)
float x, y, z;
{
int c;
if ((x == 0) && (y == 0) && (z == 0)) return(DXF_VERTICES*MAX_SAVE);
for (c=0;c<DXF_VERTICES*MAX_SAVE;++c) {
if ((x == prev_xyz[c][0]) &&
(y == prev_xyz[c][1]) &&
(z == prev_xyz[c][2])) {
return(c);
}
}
return(c);
}
bubble_up(x,y,z,index)
float x,y,z;
unsigned long index;
{
int c,d;
for (c=1;c<DXF_VERTICES*MAX_SAVE;++c) {
d = c - 1;
prev_xyz[d][0] = prev_xyz[c][0];
prev_xyz[d][1] = prev_xyz[c][1];
prev_xyz[d][2] = prev_xyz[c][2];
prev_index[d] = prev_index[c];
}
d = c - 1;
prev_index[d] = index;
prev_xyz[d][0] = x;
prev_xyz[d][1] = y;
prev_xyz[d][2] = z;
return(0);
}
getline(fp,buf)
FILE *fp;
unsigned char *buf;
{
int c=0,d=0;
while((c=getc(fp)) != EOF) {
if (c == CR) continue;
if (c == LF) break;
++d;
*buf++ = c;
}
*buf = 0;
return(d);
}
syntax(ptr)
char *ptr;
{
printf("%s infile[.DXF] [outfile[.OBJ]] [-d]\n",ptr);
exit(1);
}
rev_long(buf)
unsigned char *buf;
{
char bfr[2];
bfr[0] = buf[0];
bfr[1] = buf[1];
buf[0] = buf[3];
buf[1] = buf[2];
buf[2] = bfr[1];
buf[3] = bfr[0];
return(0);
}
rev_int(buf)
unsigned char *buf;
{
char s;
s = buf[0];
buf[0] = buf[1];
buf[1] = s;
return(0);
}
/*
area = 0.5 * ( ( x[0] * y[1] ) + ( x[1] * y[2] ) + ( x[2] * y[0] ) -
( x[1] * y[0] ) - ( x[2] * y[1] ) - ( x[0] * y[2] ) );
and the area of a planar polygon is given by
area = 0.0;
for ( i = 0; i < n - 1; i++ )
area += ( x[i] * y[i + 1] ) - ( x[i + 1] * y[i] );
area += ( x[n - 1] * y[0] ) - ( x[0] * y[n - 1] );
area /= 2.0;
If the area is a negative number, the polygon or triangle is clockwise,
if positive, it is counterclockwise. This is for the x-y plane of view.
If the polygon area is 0 then the polygon is not "viewed" from the x-y plane.
*/
poly_area_xy()
{
int c=0,d=0;
if (POLY.vertices == 3) {
area = 0.5 * ( ( (double)POLY.xyz[0][0] * (double)POLY.xyz[1][2] ) +
( (double)POLY.xyz[1][0] * (double)POLY.xyz[2][2] ) +
( (double)POLY.xyz[2][0] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[1][0] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[2][0] * (double)POLY.xyz[1][2] ) -
( (double)POLY.xyz[0][0] * (double)POLY.xyz[2][2] ) );
}
else {
area = 0.0;
for (c=0;c<POLY.vertices-1;++c)
area += ( (double)POLY.xyz[c][0] * (double)POLY.xyz[c+1][2] ) -
( (double)POLY.xyz[c+1][0] * (double)POLY.xyz[c][2] );
area += ( (double)POLY.xyz[POLY.vertices-1][0] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[0][0] * (double)POLY.xyz[POLY.vertices-1][2] );
area /= 2.0;
}
if (area < 0.0) {
++xycpoly;
++xypols;
for(c=0;c<POLY.vertices;++c) POLS.pols_points[c+1] = POLY.index[c];
return(0);
}
if (area > 0.0) {
++xyccpoly;
++xypols;
for(c=0,d=POLY.vertices;c<POLY.vertices;++c,--d) {
POLS.pols_points[d] = POLY.index[c];
}
return(0);
}
if (area == 0.0) poly_area_yz();
return(0);
}
poly_area_yz()
{
int c=0,d=0;
if (POLY.vertices == 3) {
area = 0.5 * ( ( (double)POLY.xyz[0][1] * (double)POLY.xyz[1][2] ) +
( (double)POLY.xyz[1][1] * (double)POLY.xyz[2][2] ) +
( (double)POLY.xyz[2][1] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[1][1] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[2][1] * (double)POLY.xyz[1][2] ) -
( (double)POLY.xyz[0][1] * (double)POLY.xyz[2][2] ) );
}
else {
area = 0.0;
for (c=0;c<POLY.vertices-1;++c)
area += ( (double)POLY.xyz[c][1] * (double)POLY.xyz[c+1][2] ) -
( (double)POLY.xyz[c+1][1] * (double)POLY.xyz[c][2] );
area += ( (double)POLY.xyz[POLY.vertices-1][1] * (double)POLY.xyz[0][2] ) -
( (double)POLY.xyz[0][1] * (double)POLY.xyz[POLY.vertices-1][2] );
area /= 2.0;
}
if (area < 0.0) {
++yzcpoly;
++yzpols;
for(c=0;c<POLY.vertices;++c) POLS.pols_points[c+1] = POLY.index[c];
return(0);
}
if (area > 0.0) {
++yzccpoly;
++yzpols;
for(c=0,d=POLY.vertices;c<POLY.vertices;++c,--d) {
POLS.pols_points[d] = POLY.index[c];
}
return(0);
}
if (area == 0.0) poly_area_xz();
return(0);
}
poly_area_xz()
{
int c=0,d=0;
if (POLY.vertices == 3) {
area = 0.5 * ( ( (double)POLY.xyz[0][0] * (double)POLY.xyz[1][1] ) +
( (double)POLY.xyz[1][0] * (double)POLY.xyz[2][1] ) +
( (double)POLY.xyz[2][0] * (double)POLY.xyz[0][1] ) -
( (double)POLY.xyz[1][0] * (double)POLY.xyz[0][1] ) -
( (double)POLY.xyz[2][0] * (double)POLY.xyz[1][1] ) -
( (double)POLY.xyz[0][0] * (double)POLY.xyz[2][1] ) );
}
else {
area = 0.0;
for (c=0;c<POLY.vertices-1;++c)
area += ( (double)POLY.xyz[c][0] * (double)POLY.xyz[c+1][1] ) -
( (double)POLY.xyz[c+1][0] * (double)POLY.xyz[c][1] );
area += ( (double)POLY.xyz[POLY.vertices-1][0] * (double)POLY.xyz[0][1] ) -
( (double)POLY.xyz[0][0] * (double)POLY.xyz[POLY.vertices-1][1] );
area /= 2.0;
}
if (area < 0.0) {
++xzcpoly;
++xzpols;
for(c=0;c<POLY.vertices;++c) POLS.pols_points[c+1] = POLY.index[c];
return(0);
}
if (area > 0.0) {
++xzccpoly;
++xzpols;
for(c=0,d=POLY.vertices;c<POLY.vertices;++c,--d) {
POLS.pols_points[d] = POLY.index[c];
}
return(0);
}
if (area == 0.0) {
++nonpols;
for(c=0;c<POLY.vertices;++c) POLS.pols_points[c+1] = POLY.index[c];
}
return(0);
}